@use '@material/checkbox' as mdc-checkbox;
@use '@material/checkbox/checkbox-theme' as mdc-checkbox-theme;
@use '@material/form-field' as mdc-form-field;
@use '@material/ripple' as mdc-ripple;
@use 'sass:map';
@use '../../cdk/a11y/a11y';
@use '../mdc-helpers/mdc-helpers';
@use '../../material/core/style/_layout-common.scss';

@include mdc-checkbox.without-ripple($query: mdc-helpers.$mat-base-styles-query);
@include mdc-form-field.core-styles($query: mdc-helpers.$mat-base-styles-query);

// Apply base styles to the MDC ripple to adjust appearance for state changes (hover, focus, press)
@mixin _ripple-base-styles() {
  .mdc-checkbox__ripple {
    opacity: 0;
  }
}

.mat-mdc-checkbox {
  // The host node defaults to `diplay: inline` so
  // we have to change it in order for margins to work.
  display: inline-block;

  // The MDC checkbox styles related to the hover state are intertwined with the MDC ripple styles.
  // We currently don't use the MDC ripple due to size concerns, therefore we need to add some
  // additional styles to restore the hover state.
  .mdc-checkbox:hover .mdc-checkbox__native-control:not([disabled]) ~ .mdc-checkbox__ripple {
    opacity: map.get(mdc-ripple.$dark-ink-opacities, hover);
    transform: scale(1);
    transition: mdc-checkbox-transition-enter(opacity, 0, 80ms),
    mdc-checkbox-transition-enter(transform, 0, 80ms);
  }

  // Note that the :not([disabled]) here isn't necessary, but we need it for the
  // extra specificity so that the hover styles don't override the focus styles.
  .mdc-checkbox .mdc-checkbox__native-control:not([disabled]):focus ~ .mdc-checkbox__ripple {
    opacity: map.get(mdc-ripple.$dark-ink-opacities, hover) +
      map.get(mdc-ripple.$dark-ink-opacities, focus);

    @include a11y.high-contrast(active, off) {
      outline: solid 3px;
      opacity: 1;
    }
  }

  // Angular Material supports disabling all animations when NoopAnimationsModule is imported.
  // TODO(mmalerba): Look into using MDC's Sass queries to separate the animation styles and
  //  conditionally add them. Consider the size cost when deciding whether to switch.
  &._mat-animation-noopable {
    *,
    *::before {
      transition: none !important;
      animation: none !important;
    }
  }

  // The MDC styles result in extra padding if the label is present but empty. To fix this we hide
  // the label when it is empty.
  label:empty {
    display: none;
  }

  @include _ripple-base-styles();
}

.mat-mdc-checkbox-ripple, .mdc-checkbox__ripple {
  @include layout-common.fill();

  // Usually the ripple radius would be specified through the MatRipple input, but
  // since we dynamically adjust the size of the ripple container, we cannot use a
  // fixed ripple radius.
  border-radius: 50%;
  pointer-events: none;

  // Fixes the ripples not clipping to the border radius on Safari. Uses `:not(:empty)`
  // in order to avoid creating extra layers when there aren't any ripples.
  &:not(:empty) {
    transform: translateZ(0);
  }
}
